package com.szrca.ima.utils;

import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * 丝路支付签名工具类
 * 其他系统调用支付系统时,需要用指定的私钥加密;支付系统用指定的公钥解密
 * Created by wangjinbiao on 2017/3/28.
 */
public class SignValidUtil {

    public static final String ALGORITHM = "DSA";
    public static final String PUBLIC_KEY_CACHE = "public_key";
    public static final String PRIVATE_KEY_CACHE = "private_key_cache";
    public static final String ALIPAY_PUBLIC_KEY="MIIBuDCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYUAAoGBAOzfdlvuBHCNjdbsVOoRMEo2Xez37Dz+JWv5/tn01mwC/ZkBKpATDWCv/+pdFjUyYwhXZSI1I4PkZva7fgSHFzgmjy8mAk0j2g40xsNTq2QjgagWL2GfkpOdJp+9KMz6pYbbz6gVGmv7I/SG5xc+2b5sRHuGDIFnJiqKBHFeaWQj";

    /**
     * 根据系统名称,获取公钥
     *
     * @param sysname
     * @return
     */
    public static PublicKey getPublicKeyBySysname(String sysname) {
//        Object o = CacheUtils.get(PUBLIC_KEY_CACHE, sysname);
//        if (o != null) return (PublicKey) o;

        PublicKey publicKey = getPublicKey(ALIPAY_PUBLIC_KEY);
//        if (publicKey != null) CacheUtils.put(PUBLIC_KEY_CACHE, sysname, publicKey);
        return publicKey;
    }

    /**
     * 公钥字符串转换为公钥
     *
     * @param publicKeyStr
     * @return
     */
    public static PublicKey getPublicKey(String publicKeyStr) {
        try {
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyStr));
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            return publicKey;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 验证签名
     *
     * @param data
     * @param signStr
     * @return
     */
    public static boolean verify(byte[] data, String signStr) {
        try {
            PublicKey publicKey = getPublicKey(ALIPAY_PUBLIC_KEY);
            Signature signature = Signature.getInstance(publicKey.getAlgorithm());
            signature.initVerify(publicKey);
            signature.update(data);
            return signature.verify(Base64.getDecoder().decode(signStr));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 私钥签名
     *
     * @param sysname
     * @param data
     * @return
     */
    public static String privateKeySign(String sysname, byte[] data) {
        try {
            PrivateKey privateKey = getPrivateKeyBySysname(sysname);
            Signature signature = Signature.getInstance(privateKey.getAlgorithm());
            signature.initSign(privateKey);
            signature.update(data);
            byte[] sign = signature.sign();
            return Base64.getEncoder().encodeToString(sign);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static PrivateKey getPrivateKeyBySysname(String sysname) {
//        Object o = CacheUtils.get(PRIVATE_KEY_CACHE, sysname);
//        if (o != null) return (PrivateKey) o;

        PrivateKey privateKey = getPrivateKey(sysname);
//        if (privateKey != null) CacheUtils.put(PRIVATE_KEY_CACHE, sysname, privateKey);
        return privateKey;
    }

    private static PrivateKey getPrivateKey(String privateKeyStr) {
        try {
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyStr));
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
            return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        String data = "{\"sysname\":\"test\",\"originOrderNo\":\"99999999999\",\"transactionNo\":\"1111111\",\"currency\":\"cny\",\"amount\":100000,\"num\":0}";
        String s = "MCwCFHHnmWUXmeFibwuUK9FHZ9Lx+F94AhR+D2rDrur6WXLEh1v01k4PN6Y2uA==";

        PublicKey publicKey = getPublicKey("MIIBuDCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYUAAoGBAOzfdlvuBHCNjdbsVOoRMEo2Xez37Dz+JWv5/tn01mwC/ZkBKpATDWCv/+pdFjUyYwhXZSI1I4PkZva7fgSHFzgmjy8mAk0j2g40xsNTq2QjgagWL2GfkpOdJp+9KMz6pYbbz6gVGmv7I/SG5xc+2b5sRHuGDIFnJiqKBHFeaWQj");
        Signature signature2 = Signature.getInstance(publicKey.getAlgorithm());
        signature2.initVerify(publicKey);
        signature2.update(data.getBytes());
        boolean verify = signature2.verify(Base64.getDecoder().decode(s));
        System.out.println(verify);
    }

}
